<script setup lang="ts" name="GoodsSku">
import { GoodsInfo, Spec, SpecValue } from '@/types/data'
import bwPowerSet from '@/utils/power-set'
import { ref } from 'vue'

const props = defineProps<{
  goods: GoodsInfo
  skuId?: String
}>()

const emit = defineEmits<{
  (e: 'changeSku', skuId: string): void
}>()

//更改选中状态
const changeSelected = (item: Spec, sub: SpecValue) => {
  // 如果按钮被禁用
  if (sub.disabled) return
  // 如果已经选中 就取消选中
  if (sub.selected) {
    sub.selected = false
  } else {
    // 如果没有选中 就把所有的全部取消选中 然后让自己被选中
    item.values.forEach((v) => (v.selected = false))
    sub.selected = true
  }
  // 在点击规格的时候，需要更新禁用状态
  updateDisabledStatus()

  const selected = getSelectedSpec().filter((v) => v)
  if (selected.length === props.goods.specs.length) {
    const key = selected.join('★')
    // console.log(pathMap)
    // console.log(key)
    // console.log(pathMap[key])
    const [skuId] = pathMap[key]
    // 子传父
    emit('changeSku', skuId)
  } else {
    emit('changeSku', '')
  }
}

/**
 * 获取路径字典
 */
const getPathMap = () => {
  const PathMap: any = {}
  // 1.筛选掉库存为0的sku(规格+值)
  const skus = props.goods.skus.filter((item) => item.inventory > 0)
  //  2.遍历有效的sku  得到一个幂集 >>>>一个含值nameValue的新数组
  skus.forEach((item) => {
    const arr = item.specs.map((sub) => sub.valueName)
    // 3.调用powerset生成幂集
    const powerSet = bwPowerSet(arr)
    // 4.将powerset合并到一个路径字典中
    powerSet.forEach((sub) => {
      const key = sub.join('★')
      // 5. 添加key和值到路径地图pathmap中
      // 5.1 如果没有这个属性就创建  5.2有就添加
      if (key in PathMap) {
        PathMap[key].push(item.id)
      } else {
        PathMap[key] = [item.id] //注意是二维数组 新添加的id要放在数组中
      }
    })
  })
  return PathMap
}

const pathMap = getPathMap()
// console.log(pathMap)

// 获取选中的规格
const getSelectedSpec = () => {
  const arr: string[] = []
  props.goods.specs.forEach((item) => {
    const temp = item.values.find((sub) => sub.selected)
    arr.push(temp ? temp.name : '')
  })
  return arr
}

// ps：初始化默认选中要在默认禁用之前
// 设置默认值---------主要是将selected改为true
// 但sku库中没有selected  所以要通过当前sku中的specs的值，去跟goods.specs库中去对比，找到某个spec后改为true
const initSelectedSpec = () => {
  // 1.通过skuid找到当前的sku
  const sku = props.goods.skus.find((item) => item.id === props.skuId)
  // console.log(sku)
  if (sku) {
    // 2.如果sku存在 遍历所有的规格specs
    props.goods.specs.forEach((item, index) => {
      // 3.通过当前的sku  拿到默认选中的规格的值
      const value = sku.specs[index].valueName
      // console.log(value)
      // 4.与specs库中所有的specs.values对比，找到相同的 然后将其selected为true
      const specvalue = item.values.find((sub) => sub.name === value)!
      console.log(specvalue)

      specvalue.selected = true
    })
  }
}
initSelectedSpec()

//更新禁用状态
const updateDisabledStatus = () => {
  props.goods.specs.forEach((item, index) => {
    const arr = getSelectedSpec()
    item.values.forEach((sub) => {
      arr[index] = sub.name
      const key = arr.filter((v) => v).join('★')
      if (key in pathMap) {
        sub.disabled = false
      } else {
        sub.disabled = true
      }
    })
  })
}
updateDisabledStatus()
</script>

<template>
  <div class="goods-sku">
    <dl v-for="item in goods.specs" :key="item.name">
      <dt>{{ item.name }}</dt>
      <dd>
        <template v-for="sub in item.values" :key="sub.name">
          <img
            :class="{ selected: sub.selected, disabled: sub.disabled }"
            v-if="sub.picture"
            :src="sub.picture"
            alt=""
            :title="sub.name"
            @click="changeSelected(item, sub)"
          />
          <span
            v-else
            :class="{ selected: sub.selected, disabled: sub.disabled }"
            @click="changeSelected(item, sub)"
          >
            {{ sub.name }}
          </span>
        </template>
      </dd>
    </dl>
  </div>
</template>

<style scoped lang="less">
.sku-state-mixin () {
  border: 1px solid #e4e4e4;
  margin-right: 10px;
  cursor: pointer;
  &.selected {
    border-color: @xtxColor;
  }
  &.disabled {
    opacity: 0.6;
    border-style: dashed;
    cursor: not-allowed;
  }
}
.goods-sku {
  padding-left: 10px;
  padding-top: 20px;
  dl {
    display: flex;
    padding-bottom: 20px;
    align-items: center;
    dt {
      width: 50px;
      color: #999;
    }
    dd {
      flex: 1;
      color: #666;
      > img {
        width: 50px;
        height: 50px;
        margin-top: 5px;
        .sku-state-mixin ();
      }
      > span {
        display: inline-block;
        height: 30px;
        line-height: 30px;
        padding: 0 20px;
        margin-top: 5px;
        .sku-state-mixin ();
      }
    }
  }
}
</style>
